Id Kong
2010-Feb-18 00:05 UTC
[theora-dev] Is TH_ENCCTL_SET_DUP_COUNT compatible with TH_ENCCTL_SET_VP3_COMPATIBLE?
Is the encoding control command TH_ENCCTL_SET_DUP_COUNT compatible with the TH_ENCCTL_SET_VP3_COMPATIBLE setting? I don''t see why it couldn''t be but when I try it, I get a lot of green in my video. The funny thing is that there are occasionally long (in comparison, like a second or so) periods where the video is fine. This is remarkable because, as a test, I encoded video with double the frame rate but double the frames using TH_ENCCTL_SET_DUP_COUNT so if there were a problem, you''d expect that problem to be consistent and ubiquitous. However, that''s not what I''m seeing. The green is prevalent but there are short periods where it seems to work in TH_ENCCTL_SET_VP3_COMPATIBLE mode. Can anyone shed any light on this? Thank you... Incidentally, I''m sorry if this post is poorly formatted. I''m beginning to think that hotmail is an awful mail client... ...and thank you all for your help so far! _________________________________________________________________ -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/theora-dev/attachments/20100217/a122e620/attachment.htm
Timothy B. Terriberry
2010-Feb-18 00:15 UTC
[theora-dev] Is TH_ENCCTL_SET_DUP_COUNT compatible with TH_ENCCTL_SET_VP3_COMPATIBLE?
Id Kong wrote:> Is the encoding control command TH_ENCCTL_SET_DUP_COUNT compatible with > the TH_ENCCTL_SET_VP3_COMPATIBLE setting?It should be. Can you upload some input that exhibits the problem and (hopefully) the source code you''re using to set the dup counts, or at least the actual counts used with that input?
Id Kong
2010-Feb-18 09:18 UTC
[theora-dev] Is TH_ENCCTL_SET_DUP_COUNT compatible with TH_ENCCTL_SET_VP3_COMPATIBLE?
> Date: Wed, 17 Feb 2010 19:15:55 -0500 > From: tterribe at email.unc.edu > > Id Kong wrote: > > Is the encoding control command TH_ENCCTL_SET_DUP_COUNT compatible with > > the TH_ENCCTL_SET_VP3_COMPATIBLE setting? > > It should be. Can you upload some input that exhibits the problem and > (hopefully) the source code you''re using to set the dup counts, or at > least the actual counts used with that input?I''ve created a small sample program that exhibits the behavior. I''ve created video with this program with and without the TH_ENCCTL_SET_DUP_COUNT used for each frame and I''ve played back the results with ffdshow tryout revision 1980 (Jun 2, 2008. I found the about box!) and with VLC player 1.0.2 (Goldeneye), so I have two different players and two different ogg/theora streams... ffdshow has trouble playing this particular TH_ENCCTL_SET_VP3_COMPATIBLE file, without any TH_ENCCTL_SET_DUP_COUNT, for some odd reason since it plays other ogg/theora files with these properties just fine. It plays the first little bit but quickly thinks it''s reached the end of the file when it''s really nowhere close... VLC has no trouble playing this particular TH_ENCCTL_SET_VP3_COMPATIBLE file lacking any TH_ENCCTL_SET_DUP_COUNT. ffdshow exhibits the strange green behavior I mentioned in my original post with both the TH_ENCCTL_SET_VP3_COMPATIBLE setting and with TH_ENCCTL_SET_DUP_COUNT applied to every frame, as you can see in the code. All the timing works but the green is definitely a bug! VLC can play the file with no green but it''s obviously wrong about the timing. It starts off with just black, then it sometimes plays smoothly, as if there are no duplicate frames, but occasionally pauses, way too long to simply be an additional frame, as was coded in the program. It''s as if it ignores the use of TH_ENCCTL_SET_DUP_COUNT until they pile up and it''s forced to use them up all at once. Here''s my sample program. Like my previous sample program, it uses CxImage, so if you want to actually compile the program, I can create an include file with this image statically created in C++ syntax... Thank you for your help! #include <stdio.h>//#include <conio.h>#include <assert.h> #include "CxImage\ximage.h"#include "theora\theoraenc.h"#include "theora\codec.h" int const frame_rate = 30;//int const num_frames = frame_rate * 10;int const width = 320;int const height = 240; int RoundTo16(int in) { return (in + 15) / 16 * 16;} unsigned char TransformPixel(int *tables, RGBQUAD colour) { return static_cast<unsigned char>(tables[0] + (tables[1] * colour.rgbRed + tables[2] * colour.rgbGreen + tables[3] * colour.rgbBlue) / 256);} void WriteOggPage(FILE *file, ogg_stream_state *state, bool flush = false) { while(true) { ogg_page page; int rc; if( flush ) rc = ogg_stream_flush( state, &page); else rc = ogg_stream_pageout(state, &page); if( rc == 0 ) { break; } else { fwrite(page.header, 1, page.header_len, file); fwrite(page.body, 1, page.body_len, file); } }} int main(int argc, char *argv[]) { if( argc < 3 ) { printf("Too few parameters...\n"); } else { char *input_filename = argv[1]; char *output_filename = argv[2]; CxImage image; image.Load(input_filename); if( image.IsValid() ) { printf("Loaded image!\n"); th_info theora_input; th_info_init(&theora_input); theora_input.frame_width = RoundTo16(width); theora_input.frame_height = RoundTo16(height); theora_input.pic_width = width; theora_input.pic_height = height; theora_input.pic_x = 0; theora_input.pic_y = 0; theora_input.colorspace = TH_CS_UNSPECIFIED; theora_input.pixel_fmt = TH_PF_420; theora_input.quality = 42; theora_input.target_bitrate = 0; theora_input.fps_numerator = frame_rate; theora_input.fps_denominator = 1; theora_input.aspect_numerator = 0; theora_input.aspect_denominator = 0; th_enc_ctx *theora_state = th_encode_alloc(&theora_input); int th_ctl = 5; th_encode_ctl(theora_state, TH_ENCCTL_GET_SPLEVEL_MAX, &th_ctl, sizeof(th_ctl)); th_encode_ctl(theora_state, TH_ENCCTL_SET_SPLEVEL , &th_ctl, sizeof(th_ctl)); th_ctl = 1; // Strangely enough, pixel format TH_PF_420 doesn''t seem to work without the TH_ENCCTL_SET_VP3_COMPATIBLE setting... th_encode_ctl(theora_state, TH_ENCCTL_SET_VP3_COMPATIBLE, &th_ctl, sizeof(th_ctl)); ogg_stream_state ogg_state; ogg_stream_init(&ogg_state, 3001); // Yeah, I know... FILE* output_file = fopen(output_filename, "wb"); ogg_packet packet; bool go = true; th_comment comment; th_comment_init(&comment); int rc = th_encode_flushheader(theora_state, &comment, &packet); ogg_stream_packetin(&ogg_state, &packet); // Can this really fail? WriteOggPage(output_file, &ogg_state, true); while(true) { int rc = th_encode_flushheader(theora_state, &comment, &packet); //printf("%i\n", packet.packetno); if( rc == 0) { printf("Done headers!\n"); break; } else { printf("Another packet...\n"); } ogg_stream_packetin(&ogg_state, &packet); // Can this really fail? } WriteOggPage(output_file, &ogg_state, true); if( go ) { printf("Preparing frame...\n"); th_ycbcr_buffer buffer; int tables[][4] = {{16, 66, 129, 25}, {128, -38, -74, 112}, {128, 112, -94, -18}}; printf("Encoding video...\n"); int num_frames = image.GetWidth() - width; for(int i = 0; i < num_frames; i++) { // Fill the buffer with a pan of a small subset of the image so // that we are encoding animation and not just a static image... for(int j = 0; j < 3; j++) { th_img_plane *plane = buffer + j; if( j == 0 ) { plane->width = theora_input.pic_width; plane->height = theora_input.pic_height; } else { plane->width = theora_input.pic_width / 2; plane->height = theora_input.pic_height / 2; } plane->stride = plane->width; plane->data = new unsigned char[plane->width * plane->height]; for(DWORD y = 0; y < height; y++) { for(DWORD x = 0; x < width; x++) { // the sum x + i creates our animation... if( j == 0 ) plane->data[y * plane->stride + x ] = TransformPixel(tables[j], image.GetPixelColor(x + i, height - y, false)); else if( x % 2 == 0 && y % 2 == 0 ) plane->data[y * plane->stride / 2 + x / 2] = TransformPixel(tables[j], image.GetPixelColor(x + i, height - y, false)); } } } int dupes = 1; th_encode_ctl(theora_state, TH_ENCCTL_SET_DUP_COUNT, &dupes, sizeof(dupes)); int rc = th_encode_ycbcr_in(theora_state, buffer); if( rc == 0 ) { while(true) { int rc = th_encode_packetout(theora_state, (i == num_frames - 1) ? 1 : 0, &packet); if( rc == 0 ) break; ogg_stream_packetin(&ogg_state, &packet); } WriteOggPage(output_file, &ogg_state); } else { printf("Encoding error was encountered!\n"); break; } } WriteOggPage(output_file, &ogg_state, true); for(int i = 0; i < 3; i++) { delete [] buffer[i].data; } fclose(output_file); printf("Done encoding!\n"); } ogg_stream_clear(&ogg_state); th_encode_free(theora_state); } else { printf("Bad image input...\n"); } } //_getch(); return 0;} _________________________________________________________________ Introducing Windows? phone. http://go.microsoft.com/?linkid=9708122 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/theora-dev/attachments/20100218/0ddcec02/attachment-0001.htm
Id Kong
2010-Feb-24 03:31 UTC
[theora-dev] Is TH_ENCCTL_SET_DUP_COUNT compatible with TH_ENCCTL_SET_VP3_COMPATIBLE?
> Date: Tue, 23 Feb 2010 20:29:40 -0500 > From: tterribe at email.unc.edu > > Id Kong wrote: > > Hello! Have you had a chance to look at this issue? If not, will you > > be able to look into it in the near future? Did or will my sample > > program help in any way? > > I have not... since your problems appear to be with 3rd party software, > they most likely do not support 0-byte packets properly at all. It may > be possible to work around the issue by emitting explicit frames with no > blocks coded (which are about 9 bytes each) in VP3 compatibility mode, > but depending on what you''re using SET_DUP_COUNT for, this may be a poor > substitute. I can probably find some time this weekend to confirm my > hypothesis with the help of your program.Thank you for your response. I''m using TH_ENCCTL_SET_DUP_COUNT for the purpose I believe it was intended for: simulating variable frame rate video. It turns out that the frame rate of the video I am generating varies (since it''s very dynamic and simply generates frames as quickly as it can in real time) so the video moves greatly out of sync with the captured audio, even when the average frame rate matches (sometimes it''ll be ahead, other times it''ll be behind). While I can sympathize with the frustration of third party software being far out of date with the current specification (few things are more infuriating than incorrect software), the reality is that compatibility is important. It''s the only reason why MS Windows still dominates the OS market. It may be worth breaking an older protocol for new gains but if the point of the TH_ENCCTL_SET_VP3_COMPATIBLE setting is to work with older, arguably broken implementations, it makes sense to modify current software to work with these implementations in that mode. In short, I''m saying that your suggested work around is well worth it if it works! If my understanding of TH_ENCCTL_SET_DUP_COUNT is correct and it is cheap to execute (it would have to be or you''d just call th_encode_ycbcr_in() with the same frame) then it should solve my problems. Nine bytes per frame is nothing! Thank you for any help you can offer! _________________________________________________________________ -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/theora-dev/attachments/20100223/5b20ad67/attachment.htm